#include "get_input_file.h"

void Get_Info::get_SP() {
  std::ifstream file;
  file.open(Input_File);

  if (!file) {
    std::cout << "wrong at Input file path" << std::endl;
    exit(0);
  }
  int Flag_R = -1;
  string Type;
  string flag;
  char u1[256]; // unuse
  while (!file.eof()) {
    file >> flag;
    // file.getline(u1, 256, '\n');
    // cout<<flag<<endl;
    if (flag == "[SP_Info]") {
      Flag_R = 1;
      file >> Type;
      sp_info.Type = Type;
      file.getline(u1, 256, '\n');
      if (Type == "E_max") {
        if (output_flag > 0)
          cout << "[TP_Info] E_max" << endl;
        file >> sp_info.E_max;
        file.getline(u1, 256, '\n');
        if (output_flag > 0) {
          cout << "  Emax : " << sp_info.E_max << endl;
          cout << endl;
        }
        sp_info.sp_vec.clear();
        // break;
      } else if (Type == "Read") {
        if (output_flag > 0)
          cout << "[SP_Info] Read" << endl;
        int size;
        file >> size;
        file.getline(u1, 256, '\n');
        if (output_flag > 0)
          cout << size << "   single particle number" << endl;
        file.getline(u1, 256, '\n');
        sp_info.sp_vec.resize(size);
        if (output_flag > 0)
          cout << "tz 	n 	l 	j2 	E 	index" << endl;
        for (int i = 0; i < size; i++) {
          sp_info.sp_vec[i].resize(6);
          for (int j = 0; j < 6; j++) {
            file >> sp_info.sp_vec[i][j];
            if (output_flag > 0)
              cout << sp_info.sp_vec[i][j] << "\t";
          }
          if (output_flag > 0)
            cout << endl;
        }
      } else {
        cerr << "Wrrong @ Read [SP_Info] should be: E_max or Read " << endl;
        cerr << "  Type : " << Type << endl;
        exit(0);
      }
    } else {
      file.getline(u1, 256, '\n');
    }
  }
  file.close();
  if (Flag_R < 0) {
    cerr << " Wrong @ Get_Info::get_SP() " << endl;
    cerr << " Can't Find [SP_Info] " << endl;
    exit(0);
  }
  if (output_flag > 0)
    cout << " --- Finished get_SP_input() --- " << endl;
}

void Get_Info::get_Coeff_Para() {
  std::ifstream file;
  file.open(Input_File);
  if (!file) {
    std::cout << "wrong at Input file path" << std::endl;
    exit(0);
  }
  int Flag_R = -1;
  string Type;
  string flag;
  char u1[256]; // unuse
  this->coeff_para.J_max_cg = 10;
  this->coeff_para.J_max_sixJ = 14;
  this->coeff_para.n_max_bino = 100;
  // cout<<"  J_max_cg = "<<coeff_para.J_max_cg<<endl;
  // cout<<"  J_max_sixJ = "<<coeff_para.J_max_sixJ<<endl;
  // cout<<"  n_max_bino = "<<coeff_para.n_max_bino<<endl;
  while (!file.eof()) {
    file >> flag;
    file.getline(u1, 256, '\n');
    if (flag == "[Coeff_Para]") {
      Flag_R = 1;
      int J_cg = 0;
      int J_sixJ = 0;
      int n_max = 0;
      file >> J_cg;
      file.getline(u1, 256, '\n');
      file >> J_sixJ;
      file.getline(u1, 256, '\n');
      file >> n_max;
      file.getline(u1, 256, '\n');
      this->coeff_para.J_max_cg = J_cg;
      this->coeff_para.J_max_sixJ = J_sixJ;
      this->coeff_para.n_max_bino = n_max;
      if (output_flag > 0) {
        cout << coeff_para.J_max_cg << "     coeff_para.J_max_cg " << endl;
        cout << coeff_para.J_max_sixJ << "     coeff_para.J_max_sixJ " << endl;
        cout << coeff_para.n_max_bino << "     coeff_para.n_max_bino " << endl;
      }
    }
  }
  file.close();
  if (Flag_R < 0) {
    cout << " Don't read [Coeff_Para] & Use default value " << endl;
    cout << "  J_max_cg = " << coeff_para.J_max_cg << endl;
    cout << "  J_max_sixJ = " << coeff_para.J_max_sixJ << endl;
    cout << "  n_max_bino = " << coeff_para.n_max_bino << endl;
  }
  // return;
}

void Get_Info::get_Trans_Test() {
  std::ifstream file;
  file.open(Input_File);
  if (!file) {
    std::cout << "wrong at Input file path" << std::endl;
    exit(0);
  }
  int Flag_R = -1;
  int Flag_Test = -1;
  trans_test.Trans_Test_Flag = Flag_Test;
  string Type;
  string flag;
  char u1[256]; // unuse
  while (!file.eof()) {
    file >> flag;
    //cout<<flag<<endl;
    if (flag == "[Trans_Test_Info]") {
      Flag_R = 1;
      file >> Flag_Test;
      cout<< "Flag Test : "<<Flag_Test<<endl;
      trans_test.Trans_Test_Flag = Flag_Test;
      file.getline(u1, 256, '\n');
      string filename;
      file>>filename;
      trans_test.trans_file_std = filename;
      break;
    }
    file.getline(u1, 256, '\n');
  }
  if (Flag_R < 0) {
    cerr << " Don't Read [Trans_Test_Info] donnot Test Trans " << endl;
  }
  file.close();
}

void Get_Info::get_Wave_Info() {
  std::ifstream file;
  file.open(Input_File);
  if (!file) {
    std::cout << "wrong at Input file path" << std::endl;
    exit(0);
  }
  int Flag_R = -1;
  string Type;
  string flag;
  char u1[256]; // unuse
  while (!file.eof()) {
    file >> flag;
    file.getline(u1, 256, '\n');
    // cout<<flag<<endl;

    if (flag == "[Wave_Info]") {
      Flag_R = 1;
      file >> wave_info.Lambda_Cut;
      file.getline(u1, 256, '\n');
      file >> wave_info.hbar_omega;
      file.getline(u1, 256, '\n');
      file >> wave_info.regulator_power;
      file.getline(u1, 256, '\n');
      file >> wave_info.k_mesh;
      file.getline(u1, 256, '\n');
      file >> wave_info.k_scale;
      file.getline(u1, 256, '\n');
      file >> wave_info.p_mesh;
      file.getline(u1, 256, '\n');
      file >> wave_info.EF_max;
      file.getline(u1, 256, '\n');
      file >> wave_info.EI_max;
      file.getline(u1, 256, '\n');
      file >> wave_info.n_max;
      file.getline(u1, 256, '\n');
      file >> wave_info.l_max;
      file.getline(u1, 256, '\n');
      file >> wave_info.lbarS;
      file.getline(u1, 256, '\n');
      file >> wave_info.lbarS_G;
      file.getline(u1, 256, '\n');
      file >> wave_info.lbarS_P;
      file.getline(u1, 256, '\n');
    }
  }
  if (Flag_R < 0) {
    cerr << " Wrong @ Get_Info::get_Wave_Info() " << endl;
    cerr << " Can't Find [Wave_Info] " << endl;
    exit(0);
  }
  if (output_flag > 0) {
    cout << wave_info.Lambda_Cut;
    cout << "  // Lambda_Cut" << endl;
    cout << wave_info.hbar_omega;
    cout << "  // hbar_omega" << endl;
    cout << wave_info.regulator_power;
    cout << "  // regulator_power" << endl;
    cout << wave_info.k_mesh;
    cout << "  // k_mesh" << endl;
    cout << wave_info.k_scale;
    cout << "  // k_scale" << endl;
    cout << wave_info.p_mesh;
    cout << "  // p_mesh" << endl;
    cout << wave_info.EF_max;
    cout << "  // EF_max" << endl;
    cout << wave_info.EI_max;
    cout << "  // EI_max" << endl;
    cout << wave_info.n_max;
    cout << "  // n_max" << endl;
    cout << wave_info.l_max;
    cout << "  // l_max" << endl;
    cout << wave_info.lbarS;
    cout << "  // lbarS" << endl;
    cout << wave_info.lbarS_G;
    cout << "  // lbarS_G" << endl;
    cout << wave_info.lbarS_P;
    cout << "  // lbarS_P" << endl;
  }
  //
  file.close();
  if (output_flag > 0)
    cout << " --- Finished get_Wave_Info_input() --- " << endl;
}

void Get_Info::get_TP_allow() {
  std::ifstream file;
  file.open(Input_File);
  if (!file) {
    std::cout << "wrong at Input file path" << std::endl;
    exit(0);
  }
  int Flag_R = -1;
  string Type;
  string flag;
  char u1[256]; // unuse
  while (!file.eof()) {
    file >> flag;
    // file.getline(u1, 256, '\n');
    // cout<<flag<<endl;
    if (flag == "[TP_allow_file]") {
      Flag_R = 1;
      int Num = 0;
      file >> Num;
      file.getline(u1, 256, '\n');
      tp_al_info.resize(Num);
      if (output_flag > 0)
        cout << "  [TP_allow_file]  " << Num << endl;
      for (int i = 0; i < Num; i++) {
        file >> tp_al_info[i].E_cut;
        if (output_flag > 0)
          cout << tp_al_info[i].E_cut << endl;
        file.getline(u1, 256, '\n');
        file >> tp_al_info[i].Same_particle_Flag;
        if (output_flag > 0)
          cout << tp_al_info[i].Same_particle_Flag << endl;
        file.getline(u1, 256, '\n');
        tp_al_info[i].tp_al_vec.resize(6);
        for (int j = 0; j < 6; j++) {
          tp_al_info[i].tp_al_vec[j].resize(3);
          file >> tp_al_info[i].tp_al_vec[j][0];
          file >> tp_al_info[i].tp_al_vec[j][1];
          file >> tp_al_info[i].tp_al_vec[j][2];
          file.getline(u1, 256, '\n');
          if (output_flag > 0) {
            cout << tp_al_info[i].tp_al_vec[j][0] << "\t ";
            cout << tp_al_info[i].tp_al_vec[j][1] << "\t ";
            cout << tp_al_info[i].tp_al_vec[j][2] << endl;
          }
        }
      }
    }
  }
  file.close();
  if (Flag_R < 0) {
    cerr << " Wrong @ Get_Info::get_TP_allow() " << endl;
    cerr << " Can't Find [TP_allow_file] " << endl;
    exit(0);
  }
  if (output_flag > 0)
    cout << " --- Finished get_TP_allow_input() --- " << endl;
}

void Get_Info::print(std::string filename) {
  std::ofstream file;
  file.open(filename);
  file << "  ==========================================================="
       << endl;
  file << "      __        __           ___  __   __   ___  __   ___    "
       << endl;
  file << "     |  \\  /\\  |__) |__/    |__  |__) /  \\ |__  /__`  |     "
       << endl;
  file << "     |__/ /--\\ |  \\ |  \\    |    |  \\ \\__/ |___ .__/  |    "
       << endl;

  file << "                                                             "
       << endl;
  file << "                         version 2.1                         "
       << endl;
  file << "                     by Yuanzhuo 2020-June                   "
       << endl;
  file << "    ------------------------------------------------------   "
       << endl;
  file << endl;
  Time_Count TC;
  TC.print_time(file);
  file << endl;
  cout << " Start SP type " << endl;
  file << "   -- Generate by get_input_file.print() -- " << endl;
  file << "# Get SP Info : E_max or Read" << endl;
  if (sp_info.Type == "E_max") {
    file << "[SP_Info]  E_max" << endl;
    file << sp_info.E_max << endl;
  } else {
    file << "[SP_Info]  Read" << endl;
    file << sp_info.SP_Num << "  single particle number" << endl;
    file << "tz 	n 	l 	j2 	E 	index" << endl;
    for (int i = 0; i < sp_info.SP_Num; i++) {
      for (int j = 0; j < 6; j++) {
        file << sp_info.sp_vec[i][j] << "\t ";
      }
      file << endl;
    }
  }
  file << endl;
  cout << " Start TP type " << endl;
  file << endl;
  file << "# Get TP type : E_max or abc" << endl;
  if (tp_info.Type == "E_max") {
    file << "[TP_Info]  E_max" << endl;
    file << tp_info.E_max << "  #E_a + E_b + E_c <= Emax" << endl;
  } else {
    file << "[TP_Info]  abc" << endl;

    file << tp_info.abc_vec[0] << "  //a_min " << endl;
    file << tp_info.abc_vec[1] << "  //a_max " << endl;
    file << tp_info.abc_vec[2] << "  //b_min " << endl;
    file << tp_info.abc_vec[3] << "  //b_max " << endl;
    file << tp_info.abc_vec[4] << "  //c_min " << endl;
    file << tp_info.abc_vec[5] << "  //c_max " << endl;
  }
  file << endl;
  file << endl;
  cout << " Start TP ty " << endl;
  file << "# Get TP_allow file : number" << endl;
  int tp_al_num = tp_al_info.size();
  file << "[TP_allow_file]  " << tp_al_num << endl;
  for (int i = 0; i < tp_al_num; i++) {
    file << tp_al_info[i].E_cut
         << "  //Ecut >= | e_{hole} + e_{val} - e_{particle}|" << endl;
    file << tp_al_info[i].Same_particle_Flag
         << "   // Same_particle Flag: 1)a’=a  2)b’=b 3)c’=c" << endl;
    for (int k = 0; k < 6; k++) {
      for (int j = 0; j < 3; j++)
        file << tp_al_info[i].tp_al_vec[k][j] << "\t ";
      file << "  // x_min   x_max" << endl;
    }
  }

  file << endl;
  file << endl;
  cout << " Wave Info " << endl;
  file << "# Get Wave Info" << endl;
  file << "[Wave_Info]" << endl;
  file << wave_info.Lambda_Cut << "  //Lambda_Cut" << endl;
  file << wave_info.hbar_omega << "  //hbar_omega" << endl;
  file << wave_info.regulator_power << "  //regulator_power" << endl;
  file << wave_info.k_mesh << "   //k_mesh" << endl;
  file << wave_info.k_scale << "  //k_scale " << endl;
  file << wave_info.p_mesh << "  //p_mesh " << endl;
  ;
  file << wave_info.EF_max << "  //EF_max " << endl;
  ;
  file << wave_info.EI_max << "  //EI_max " << endl;
  ;
  file << wave_info.n_max << "  //n_max " << endl;
  ;
  file << wave_info.l_max << "  //l_max " << endl;
  ;
  file << wave_info.lbarS << "  //lbarS " << endl;
  ;
  file << wave_info.lbarS_G << "  //lbarS_G " << endl;
  ;
  file << wave_info.lbarS_P << "  //lbarS_P " << endl;
  ;

  file << endl;
  file << endl;
  file.close();
}

void Get_Info::get_TP() {
  std::ifstream file;
  file.open(Input_File);
  if (!file) {
    std::cout << "wrong at Input file path" << std::endl;
    exit(0);
  }
  int Flag_R = -1;
  string Type;
  string flag;
  char u1[256]; // unuse
  while (!file.eof()) {
    file >> flag;
    // file.getline(u1, 256, '\n');
    // cout<<flag<<endl;
    if (flag == "[TP_Info]") {
      Flag_R = 1;
      file >> Type;
      tp_info.Type = Type;
      file.getline(u1, 256, '\n');
      if (Type == "E_max") {
        if (output_flag > 0)
          cout << "[TP_Info] E_max" << endl;
        file >> tp_info.E_max;
        file.getline(u1, 256, '\n');
        if (output_flag > 0)
          cout << " Emax : " << tp_info.E_max << endl;
        if (output_flag > 0)
          cout << endl;
        tp_info.abc_vec.clear();
      } else if (Type == "abc") {
        if (output_flag > 0)
          cout << "[TP_Info] abc" << endl;
        tp_info.abc_vec.resize(6);
        if (output_flag > 0)
          cout << "\t a_min\t a_max\t b_min\t b_max\t c_min\t c_max " << endl;
        for (int i = 0; i < 6; i++) {

          file >> tp_info.abc_vec[i];
          file.getline(u1, 256, '\n');
          if (output_flag > 0)
            cout << "\t " << tp_info.abc_vec[i];
        }
        if (output_flag > 0)
          cout << endl;
      } else {
        cerr << "Wrrong @ Read [TP_Info] should be: E_max or abc " << endl;
        exit(0);
      }
    } else {
      file.getline(u1, 256, '\n');
    }
  }
  file.close();
  if (Flag_R < 0) {
    cerr << " Wrong @ Get_Info::get_TP() " << endl;
    cerr << " Can't Find [TP_Info] " << endl;
    exit(0);
  }
  if (output_flag > 0)
    cout << " --- Finished get_TP_input() --- " << endl;
}
void Get_Info_MB::get_DP_info() {
  std::ifstream file;
  file.open(Input_File);
  if (!file) {
    std::cout << "wrong at Input file path" << std::endl;
    exit(0);
  }
  int Flag_R = -1;
  string Type;
  string flag;
  char u1[256]; // unuse
  dp_info.ab_vec.resize(4);
  while (!file.eof()) {
    file >> flag;
    file.getline(u1, 256, '\n');
    if (flag == "[DP_Info]") {
      if (output_flag > 0)
        cout << "[DP_Info]" << endl;
      for (int i = 0; i < 4; i++) {
        file >> dp_info.ab_vec[i];
        if (output_flag > 0)
          cout << dp_info.ab_vec[i] << endl;
        file.getline(u1, 256, '\n');
      }
      Flag_R = 1;
    }
  }
  if (Flag_R < 0) {
    cerr << " Wrong @ Get_Info_MB::get_DP_info" << endl;
    cerr << " Can't Find [DP_Info] " << endl;
    exit(0);
  }
  file.close();
}

void Get_Info_MB::get_Model_Space_info() {
  std::ifstream file;
  file.open(Input_File);
  if (!file) {
    std::cout << "wrong at Input file path" << std::endl;
    exit(0);
  }
  int Flag_R = -1;
  string Type;
  string flag;
  char u1[256]; // unuse
  while (!file.eof()) {
    file >> flag;
    // file.getline(u1, 256, '\n');
    // cout<<u1<<endl;
    if (flag == "[Model_Space]") {
      int E_cut;
      file >> E_cut;
      file.getline(u1, 256, '\n');
      ms_info.E_cut = E_cut;
      cout << " E_cut = " << ms_info.E_cut << endl;

      file >> ms_info.sp_core >> ms_info.sp_core_Tz;
      if (output_flag > 0)
        cout << ms_info.sp_core << "\t " << ms_info.sp_core_Tz
             << "\t   #sp_core	sp_core_Tz" << endl;
      file.getline(u1, 256, '\n');
      file >> ms_info.sp_P_beg >> ms_info.sp_P_beg_Tz;
      if (output_flag > 0)
        cout << ms_info.sp_P_beg << "\t " << ms_info.sp_P_beg_Tz
             << "\t  #sp_P_beg	sp_P_beg_Tz" << endl;
      file.getline(u1, 256, '\n');
      file >> ms_info.sp_P_end >> ms_info.sp_P_end_Tz;
      if (output_flag > 0)
        cout << ms_info.sp_P_end << "\t " << ms_info.sp_P_end_Tz
             << "\t   #sp_P_end	sp_P_end_Tz" << endl;
      file.getline(u1, 256, '\n');
      file >> ms_info.sp_Q_beg >> ms_info.sp_Q_beg_Tz;
      if (output_flag > 0)
        cout << ms_info.sp_Q_beg << "\t " << ms_info.sp_Q_beg_Tz
             << "\t   #sp_P_beg	sp_P_beg_Tz" << endl;
      file.getline(u1, 256, '\n');
      file >> ms_info.sp_Q_end >> ms_info.sp_Q_end_Tz;
      if (output_flag > 0)
        cout << ms_info.sp_Q_end << "\t " << ms_info.sp_Q_end_Tz
             << "\t   #sp_P_end	sp_P_end_Tz" << endl;
      file.getline(u1, 256, '\n');
      Flag_R = 1;
      break;
    } else {
      file.getline(u1, 256, '\n');
    }
  }

  if (output_flag > 0) {
    cout << ms_info.E_cut << "\t #E_cut" << endl;
    cout << ms_info.sp_core << "\t " << ms_info.sp_core_Tz
         << "\t   #sp_core	sp_core_Tz" << endl;
    cout << ms_info.sp_P_beg << "\t " << ms_info.sp_P_beg_Tz
         << "\t  #sp_P_beg	sp_P_beg_Tz" << endl;
    cout << ms_info.sp_P_end << "\t " << ms_info.sp_P_end_Tz
         << "\t   #sp_P_end	sp_P_end_Tz" << endl;
    cout << ms_info.sp_Q_beg << "\t " << ms_info.sp_Q_beg_Tz
         << "\t   #sp_P_beg	sp_P_beg_Tz" << endl;
    cout << ms_info.sp_Q_end << "\t " << ms_info.sp_Q_end_Tz
         << "\t   #sp_P_end	sp_P_end_Tz" << endl;
  }
  if (Flag_R < 0) {
    cerr << " Wrong @ Get_Info_MB::get_Model_Space_info" << endl;
    cerr << " Can't Find [Model_Space] " << endl;
    exit(0);
  }
  file.close();
}

void Get_Info_MB::get_DP_allow_info() {
  std::ifstream file;
  file.open(Input_File);
  if (!file) {
    std::cout << "wrong at Input file path" << std::endl;
    exit(0);
  }
  int Flag_R = -1;
  string Type;
  string flag;
  char u1[256]; // unuse
  while (!file.eof()) {
    file >> flag;
    // file.getline(u1, 256, '\n');
    // cout<<flag<<endl;
    if (flag == "[DP_allow_file]") {
      Flag_R = 1;
      int Num = 0;
      file >> Num;
      file.getline(u1, 256, '\n');
      dp_al_info.resize(Num);
      if (output_flag > 0)
        cout << "  [DP_allow_file]  " << Num << endl;
      for (int i = 0; i < Num; i++) {
        file >> dp_al_info[i].E_cut;
        if (output_flag > 0)
          cout << dp_al_info[i].E_cut << endl;
        file.getline(u1, 256, '\n');
        file >> dp_al_info[i].Same_particle_Flag;
        if (output_flag > 0)
          cout << dp_al_info[i].Same_particle_Flag << endl;
        file.getline(u1, 256, '\n');
        dp_al_info[i].dp_al_vec.resize(4);
        for (int j = 0; j < 4; j++) {
          dp_al_info[i].dp_al_vec[j].resize(3);
          file >> dp_al_info[i].dp_al_vec[j][0];
          file >> dp_al_info[i].dp_al_vec[j][1];
          file >> dp_al_info[i].dp_al_vec[j][2];
          file.getline(u1, 256, '\n');
          if (output_flag > 0) {
            cout << dp_al_info[i].dp_al_vec[j][0] << "\t ";
            cout << dp_al_info[i].dp_al_vec[j][1] << "\t ";
            cout << dp_al_info[i].dp_al_vec[j][2] << endl;
          }
        }
      }
      break;
    } else {
      file.getline(u1, 256, '\n');
    }
  }
  file.close();
  if (Flag_R < 0) {
    cerr << " Wrong @ Get_Info::get_DP_allow() " << endl;
    cerr << " Can't Find [DP_allow_file] " << endl;
    exit(0);
  }
  if (output_flag > 0)
    cout << " --- Finished get_TP_allow_input() --- " << endl;
}

void Get_Info_MB::get_TBME_info() {
  std::ifstream file;
  file.open(Input_File);
  if (!file) {
    std::cout << "wrong at Input file path" << std::endl;
    exit(0);
  }
  int Flag_R = -1;
  string Type;
  string flag;
  char u1[256]; // unuse
  while (!file.eof()) {
    file >> flag;
    file.getline(u1, 256, '\n');
    // cout<<flag<<endl;
    if (flag == "[TBME_Info]") {
      file >> tbme_info.filename_orb;
      file.getline(u1, 256, '\n');
      file >> tbme_info.filename_int;
      Flag_R = 1;
      break;
    }
  }
  if (Flag_R < 0) {
    cerr << " Wrong @ Get_Info_MB::get_TBME_info" << endl;
    cerr << " Can't Find [TBME_Info] " << endl;
    exit(0);
  }
  cout << " TBME orb? : " << tbme_info.filename_orb << endl;
  cout << " TBME int? : " << tbme_info.filename_int << endl;
  file.close();
}
